package com.googlecode.horncomb.organ.srvc.support;

import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.util.Assert;

import com.googlecode.horncomb.bean.filter.SimpleMapConditionSet;
import com.googlecode.horncomb.organ.Relation;
import com.googlecode.horncomb.organ.srvc.RelationService;
import com.googlecode.horncomb.organ.support.OrganObject;
import com.googlecode.horncomb.orm.ibatis.DefaultCommonSqlMapEntityDao;

/**
 * @author Daniel
 */
@SuppressWarnings("unchecked")
public class DefaultRelationService extends DefaultCommonSqlMapEntityDao
		implements RelationService {
	private static final long serialVersionUID = -2572913094915331996L;

	// -----------------------------------------------------------
	// create
	/**
	 * {@inheritDoc}
	 */
	public void create(Relation relation) {
		Assert.notNull(relation);
		relation.setCreated(new Date());
		relation.setState(OrganObject.STATE_ACTIVE);
		relation.setLastUpdated(relation.getCreated());
		this.insert(relation);
	}

	// -----------------------------------------------------------
	// get
	/**
	 * {@inheritDoc}
	 */
	public Relation get(String sourceId, String targetId, String nature) {
		return (Relation) this.doGet(new SimpleMapConditionSet().addConstraint(
				"sourceId", sourceId).addConstraint(" targetId", targetId)
				.addConstraint("nature", nature));
	}

	/**
	 * {@inheritDoc}
	 */
	public Relation getById(String id) {
		return (Relation) this.getById(id);
	}

	// -----------------------------------------------------------
	// findRelations

	/**
	 * {@inheritDoc}
	 */
	public List<? extends Relation> findRelations(Collection<String> sourceIds,
			String targetId, String[] relationNatures) {
		return this.query(new SimpleMapConditionSet().addConstraint(
				"sourceIds", sourceIds).addConstraint("targetId", targetId)
				.addConstraint("natures", relationNatures), null);
	}

	/**
	 * {@inheritDoc}
	 */
	public List<? extends Relation> findRelations(String sourceId,
			Collection<String> targetIds, String[] relationNatures) {
		return this.query(new SimpleMapConditionSet().addConstraint("sourceId",
				sourceId).addConstraint("targetIds", targetIds).addConstraint(
				"natures", relationNatures), null);
	}

	/**
	 * {@inheritDoc}
	 */
	public List<? extends Relation> findRelations(String sourceId,
			String targetId, String[] relationNatures) {
		return this.query(new SimpleMapConditionSet().addConstraint("sourceId",
				sourceId).addConstraint(" targetId", targetId).addConstraint(
				"natures", relationNatures), null);
	}

	// -----------------------------------------------------------
	// removeBeteen
	/**
	 * {@inheritDoc}
	 */
	public void removeBetween(String sourceId, Collection<String> targetIds,
			String[] relationNatures, boolean deleted) {
		Map<String, Object> entity = new HashMap<String, Object>();
		entity.put("state", deleted ? OrganObject.STATE_DELELTED
				: OrganObject.STATE_ACTIVE);
		this.doUpdate(new SimpleMapConditionSet().addConstraint("sourceId",
				sourceId).addConstraint("targetIds", targetIds).addConstraint(
				"natures", relationNatures), entity);
	}

	/**
	 * {@inheritDoc}
	 */
	public void removeBetween(Collection<String> sourceIds, String targetId,
			String[] relationNatures, boolean deleted) {
		Map<String, Object> entity = new HashMap<String, Object>();
		entity.put("state", deleted ? OrganObject.STATE_DELELTED
				: OrganObject.STATE_ACTIVE);
		this.doUpdate(new SimpleMapConditionSet().addConstraint("sourceIds",
				sourceIds).addConstraint("targetId", targetId).addConstraint(
				"natures", relationNatures), entity);
	}

	/**
	 * {@inheritDoc}
	 */
	public void removeBetween(String sourceId, String targetId,
			String[] relationNatures, boolean deleted) {
		Map<String, Object> entity = new HashMap<String, Object>();
		entity.put("state", deleted ? OrganObject.STATE_DELELTED
				: OrganObject.STATE_ACTIVE);
		this.doUpdate(new SimpleMapConditionSet().addConstraint("sourceId",
				sourceId).addConstraint("targetId", targetId).addConstraint(
				"natures", relationNatures), entity);
	}

	// -----------------------------------------------------------
	// removeFromSource

	/**
	 * {@inheritDoc}
	 */
	public void removeFromSource(String sourceId, String[] targetNatures,
			String[] relationNatures, boolean deleted) {
		Map<String, Object> entity = new HashMap<String, Object>();
		entity.put("state", deleted ? OrganObject.STATE_DELELTED
				: OrganObject.STATE_ACTIVE);
		this.doUpdate(new SimpleMapConditionSet().addConstraint("sourceId",
				sourceId).addConstraint("targetNatures", targetNatures)
				.addConstraint("natures", relationNatures), entity);
	}

	/**
	 * {@inheritDoc}
	 */
	public void removeFromSources(Collection<String> sourceIds,
			String[] targetNatures, String[] relationNatures, boolean deleted) {
		Map<String, Object> entity = new HashMap<String, Object>();
		entity.put("state", deleted ? OrganObject.STATE_DELELTED
				: OrganObject.STATE_ACTIVE);
		this.doUpdate(new SimpleMapConditionSet().addConstraint("sourceIds",
				sourceIds).addConstraint("targetNatures", targetNatures)
				.addConstraint("natures", relationNatures), entity);
	}

	// -----------------------------------------------------------
	// removeToTarget
	/**
	 * {@inheritDoc}
	 */
	public void removeToTarget(String targetId, String[] sourceNatures,
			String[] relationNatures, boolean deleted) {
		Map<String, Object> entity = new HashMap<String, Object>();
		entity.put("state", deleted ? OrganObject.STATE_DELELTED
				: OrganObject.STATE_ACTIVE);
		this.doUpdate(new SimpleMapConditionSet().addConstraint("targetId",
				targetId).addConstraint("sourceNatures", sourceNatures)
				.addConstraint("natures", relationNatures), entity);
	}

	/**
	 * {@inheritDoc}
	 */
	public void removeToTargets(Collection<String> targetIds,
			String[] sourceNatures, String[] relationNatures, boolean deleted) {
		Map<String, Object> entity = new HashMap<String, Object>();
		entity.put("state", deleted ? OrganObject.STATE_DELELTED
				: OrganObject.STATE_ACTIVE);
		this.doUpdate(new SimpleMapConditionSet().addConstraint("targetIds",
				targetIds).addConstraint("sourceNatures", sourceNatures)
				.addConstraint("natures", relationNatures), entity);
	}

	// -----------------------------------------------------------
	// removeById
	/**
	 * {@inheritDoc}
	 */
	public void removeById(String relationshipId, boolean deleted) {
		Map<String, Object> entity = new HashMap<String, Object>();
		entity.put("state", deleted ? OrganObject.STATE_DELELTED
				: OrganObject.STATE_ACTIVE);
		this.doUpdate(new SimpleMapConditionSet().addConstraint("id",
				relationshipId), entity);
	}

	/**
	 * {@inheritDoc}
	 */
	public void removeByIds(Collection<String> relationshipIds, boolean deleted) {
		Map<String, Object> entity = new HashMap<String, Object>();
		entity.put("state", deleted ? OrganObject.STATE_DELELTED
				: OrganObject.STATE_ACTIVE);
		this.doUpdate(new SimpleMapConditionSet().addConstraint("ids",
				relationshipIds), entity);
	}
}
